﻿''' <summary>
''' ストレージ
''' </summary>
''' <remarks>
''' </remarks>
Public Class Storage

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()
    End Sub

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <param name="instance">アーカイブ対象インスタンス</param>
    ''' <remarks></remarks>
    Public Sub New(instance As Object)
        Me.Regist(instance)
    End Sub

    ''' <summary>
    ''' アーカイブコンテナ
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>アーカイブコレクション共通ロジック</remarks>
    Private Property Container As New ArchiveContainer(AddressOf Storage.ToCollection)

    ''' <summary>
    ''' コレクションに変換します
    ''' </summary>
    ''' <param name="obj">変換対象オブジェクト</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Shared Function ToCollection(obj As Object) As ICollection
        '空配列をキャッシュ
        Static blank As ICollection = DirectCast(Enumerable.Empty(Of Object)(), ICollection)

        Dim c = TryCast(obj, ICollection)
        If c IsNot Nothing Then
            Return c
        End If

        If obj IsNot Nothing Then
            Return {obj}
        End If

        '空配列を返す
        Return blank
    End Function

    ''' <summary>
    ''' アイテムクラスアーカイブ
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Archives As IEnumerable(Of ItemEntityArchive)
        Get
            Return (From el In Me.Container.Archives Select el.Value)
        End Get
    End Property

    ''' <summary>
    ''' インスタンスをアーカイブ登録します
    ''' </summary>
    ''' <param name="instance"></param>
    ''' <remarks></remarks>
    Public Function Regist(instance As Object) As Storage
        If Me.Container.Archives.Any Then
            Dim msg = My.Resources.ALREADY_ARCHIVE_REGISTED_EXCEPTION
            Throw New InvalidOperationException(msg)
        End If

        'アーカイブ登録
        Me.Container.Regist(instance)

        Return Me
    End Function

    ''' <summary>
    ''' ダーティチェックします
    ''' </summary>
    ''' <param name="instance"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsDirty(instance As Object) As Boolean
        Return Me.Container.IsDirty(instance)
    End Function

    ''' <summary>
    ''' 現在のアーカイブ情報を破棄します
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Clear() As Storage
        Me.Container.Archives.Clear()
        Return Me
    End Function

    ''' <summary>
    ''' 追加ダーティに変換します
    ''' </summary>
    ''' <param name="instance"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function ToAddDirtyObjects(instance As Object) As ICollection(Of DirtyObject)
        Return DirtyObjectCreater.ToAddDirtyObjects(instance)
    End Function

    ''' <summary>
    ''' 削除ダーティに変換します
    ''' </summary>
    ''' <param name="instance"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function ToDeleteDirtyObjects(instance As Object) As ICollection(Of DirtyObject)
        Return DirtyObjectCreater.ToDeleteDirtyObjects(instance)
    End Function

    ''' <summary>
    ''' ダーティオブジェクトに変換します
    ''' </summary>
    ''' <param name="instance"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ToDirtyObjects(instance As Object) As ICollection(Of DirtyObject)
        Return Me.Container.ToDirtyObjects(instance)
    End Function

End Class